#!/usr/bin/env python2.5

## TODO:  Modify this for a Brill tagger with the JoshTagger as backoff.

## Trains a sequential tagger upon our data.

## Usage:  ~ sentences num.sents

import sys, nltk
from nltk import tag
from nltk.tag import sequential, brill 
from nltk.tag.sequential import *
from nltk.tag.brill import *
import tokenize

def getBrillTagger(file, NUM_SENTS = 0):
	"""Creates, trains, and returns a Sequential tagger."""

	templates = [
		SymmetricProximateTokensTemplate(ProximateTagsRule, (1, 1)),
		SymmetricProximateTokensTemplate(ProximateTagsRule, (2, 2)),
		SymmetricProximateTokensTemplate(ProximateTagsRule, (1, 2)),
		SymmetricProximateTokensTemplate(ProximateTagsRule, (1, 3)),
		SymmetricProximateTokensTemplate(ProximateWordsRule, (1, 1)),
		SymmetricProximateTokensTemplate(ProximateWordsRule, (2, 2)),
		SymmetricProximateTokensTemplate(ProximateWordsRule, (1, 2)),
		SymmetricProximateTokensTemplate(ProximateWordsRule, (1, 3)),
		ProximateTokensTemplate(ProximateTagsRule, (-1, -1), (1, 1)),
		ProximateTokensTemplate(ProximateWordsRule, (-1, -1), (1, 1)),]
	default_tagger = nltk.DefaultTagger("NN")
	tagfile = open(file, 'r')
	sent = list()
	token_seq = list()
	tag_seq = list()
	training_data = list()
	RCE = 0
	for entry in tagfile:
		if ((NUM_SENTS != 0) and (NUM_SENTS == RCE)):	break
		if (entry == "\n"):
			training_data.append(sent)
			sent = list()
			continue
		entry = tokenize.tokenize(entry, 3).strip()
		sent.append(tuple([" ".join(entry.split()[:-1]), entry.split()[-1]]))
		token_seq.append(" ".join(entry.split()[:-1]))
		tag_seq.append(entry.split()[-1])
		RCE += 1
	uni = nltk.UnigramTagger(train=training_data, backoff=default_tagger)
	bi = nltk.BigramTagger(train=training_data, backoff=uni)
	brill_trainer = BrillTaggerTrainer(initial_tagger = bi, templates = templates)
	brill_tagger = brill_trainer.train(training_data, max_rules = 100)
	# tri = nltk.TrigramTagger(train=training_data, backoff=bi)
	# return (nltk.NgramTagger(N, train=training_data, backoff=tri), training_data)
	return (brill_tagger, training_data)

## Run a simple test.
if (__name__ == "__main__"):
	try:	(BTagger, train_data) = getBrillTagger(sys.argv[1], int(sys.argv[2]))
	except:	(BTagger, train_data) = getBrillTagger(sys.argv[1])
	test = list(["Inertia is a property of the Mars 's matter .".split()])
	print BTagger.batch_tag(test)
	test = list(["That has a brown fungi in the summer .".split()])
	print BTagger.batch_tag(test)
	print
	print "Accuracy:  %4.11f%%" % (100.0 * BTagger.evaluate(train_data))
